#ifndef XB_IMAGE_UTILS_H
#define XB_IMAGE_UTILS_H

#include <cstdint>
#include "ingenic_mnni.h"
#include "common/common_utils.h"
#include "data_type.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>
#include <cmath>
#include "common/common_type.h"
#include <common/common_utils_nriscv.h>
#include "utils/imgproc.h"
#include "utils/postproc.h"

namespace XBUtils{
    class ImageUtils {
        public:
            struct RGB {
                uint8_t r, g, b;};
            int static fill_dim(uint8_t *data, int h, int w);
            int static rgb2bgr(uint8_t *data, int data_cnt);
            int static frame_to_img(const FrameInfo &frame, MyImg &img);
            int static img_to_frame(const MyImg &img, FrameInfo &frame);
            int static tensor_to_img(const magik::uranus::Tensor &tensor, MyImg &img);
            int static read_img(FrameInfo &in, MyImg &img, const std::string &img_path);
            void static draw_boxes(MyImg &img, const std::vector<magik::uranus::ObjBbox_t> &boxes);        
            void static read_nv12(FrameInfo &in, const std::string &img_path, int img_w, int img_h); 
            void static nv12ToRgb(const uint8_t* nv12_data, int width, int height, uint8_t* rgb_data);
            void static saveImg(MyImg &img, std::string filename, int quality, std::string ip="192.168.3.99");
            void static saveFrameInfo(FrameInfo rgb_info, std::string filename, int quality, std::string ip="192.168.3.99");
            void static saveNV12ToJpeg(std::vector<uint8_t> data, int width, int height, std::string filename, int quality);
            void static yuvToRGB(uint8_t y, uint8_t u, uint8_t v, RGB& out_rgb);
            void static print_memory_usage_mb(const std::string& tag);
            void static crop_image(const MyImg& in_img, const magik::uranus::Box_t& box, MyImg& out_img) ;
            void static free_stb_mem(uint8_t* data);
            void static resize_image(const MyImg& src_img, MyImg& dst_img, int dst_width, int dst_height);
            int static img_to_tensor(const MyImg& src_img, magik::uranus::Tensor& out_tensor, 
                                            int dst_width, int dst_height);
            void static frametoTensor(FrameInfo &in, magik::uranus::Tensor &out);
            void static prepare_data(FrameInfo &in, 
                    magik::uranus::Tensor &out, 
                    magik::uranus::Box_t tmp_box, 
                    int input_w, 
                    int input_h,
                    magik::uranus::ChannelLayout image_format);
        };
}
#endif // XB_IMAGE_UTILS_H